import Glibc

class Timer {
    private let CLOCK_REALTIME = 0
    private var start_timespec = timespec()
    private var end_timespec = timespec()
    private var time_spec = timespec()
    func start() {
        clock_gettime(Int32(CLOCK_REALTIME),&start_timespec)
    }
    
    func stop() -> Double {
        clock_gettime(Int32(CLOCK_REALTIME),&end_timespec)
        let start_time = Double(start_timespec.tv_sec * 1_000_000 + start_timespec.tv_nsec / 1_000)
        let end_time = Double(end_timespec.tv_sec * 1_000_000 + end_timespec.tv_nsec / 1_000)
        let time = end_time - start_time
        return time / 1_000
    }
    func getTime() -> Double {
        clock_gettime(Int32(CLOCK_REALTIME),&time_spec)
        return Double(time_spec.tv_sec * 1_000_000 + time_spec.tv_nsec / 1_000)
    }
}

let timer = Timer()

func Mandelbrot() {
    let w: Int = 1000
    let h = w
    var bit_num = 0, i = 0, byte_acc = 0
    let iter = 50, limit = 2.0
    var Zr, Zi, Cr, Ci, Tr, Ti: Double
    var res = 0
    let limit2 = limit * limit

    for y in 0..<h {
        Ci = 2.0*Double(y)/Double(h) - 1.0
        for x in 0..<w {
            Zr = 0.0; Zi = 0.0; Tr = 0.0; Ti = 0.0
            Cr = 2.0*Double(x)/Double(w) - 1.5;
            i = 0
            while i < iter && (Tr+Ti <= limit2) {
                i += 1
                Zi = 2.0*Zr*Zi + Ci
                Zr = Tr - Ti + Cr
                Tr = Zr * Zr
                Ti = Zi * Zi
            }
            byte_acc <<= 1
            if Tr+Ti <= limit2 {
                byte_acc |= 0x01
            }
            bit_num += 1
            if bit_num == 8 {
                res += byte_acc
                // putc(byte_acc,stdout) // Glibc
                byte_acc = 0
                bit_num = 0
            } else if x == w-1 {
                byte_acc <<= (8-w%8)
                res += byte_acc
                // putc(byte_acc,stdout) // Glibc
                byte_acc = 0
                bit_num = 0
            }
        }
    }
    print(res)
    // return res
}

func runMandelbrot()->Int{
    timer.start()
    Mandelbrot();
    let time = timer.stop()
    // print(String(res))
    print("Array Access - RunMandelbrot:\t"+String(time)+"\tms");
    return  Int(time)  
}
_ = runMandelbrot()